part of '../repository.dart';

const _kCollectionFolderCollectionsKey = 'collections';

const _kCollectionFolderTypeValue = 'collection_folder';

class _CollectionFolderDto extends Equatable
    implements _CollectionListItemDto {
  const _CollectionFolderDto({
    required this.id,
    required this.titleDtoMap,
    required this.collectionDtos,
  });

  @override
  final String id;

  @override
  final BuiltMap<_UILocaleDto, String> titleDtoMap;

  final BuiltList<_CollectionDto> collectionDtos;

  @override
  String get type => _kCollectionFolderTypeValue;

  @override
  List<Object?> get props {
    return [
      id,
      titleDtoMap,
      collectionDtos,
    ];
  }

  factory _CollectionFolderDto.fromJson(Map<String, dynamic> json) {
    final titleMap = json[_kCollectionListItemTitlesKey] as Map;

    final titles = titleMap.map((uiLocaleString, title) {
      final uiLocale = _UILocaleDto.fromString(uiLocaleString);
      return MapEntry(uiLocale, title as String);
    }).build();

    final collectionMaps = List.castFrom<dynamic, Map>(json[_kCollectionFolderCollectionsKey]);

    final collectionDtos = collectionMaps.map((collectionMap) {
      final collectionJson = Map.castFrom<dynamic, dynamic, String, dynamic>(collectionMap);

      return _CollectionDto.fromJson(collectionJson);
    }).toBuiltList();

    return _CollectionFolderDto(
      id: json[_kCollectionListItemIdKey],
      titleDtoMap: titles,
      collectionDtos: collectionDtos,
    );
  }

  factory _CollectionFolderDto.fromEntity(CollectionFolder folder) {
    final titleDtoMap = folder.titles.map((uiLocale, title) {
      final uiLocaleDto = _UILocaleDto.fromEntity(uiLocale);
      return MapEntry(uiLocaleDto, title);
    });

    final collectionDtos = folder.collections.map((collection) {
      return _CollectionDto.fromEntity(collection);
    }).toBuiltList();

    return _CollectionFolderDto(
      id: folder.id,
      titleDtoMap: titleDtoMap,
      collectionDtos: collectionDtos,
    );
  }

  @override
  Map<String, dynamic> toJson() {
    final collectionJsons = collectionDtos.map((collectionDto) {
      return collectionDto.toJson();
    }).toList();

    final titles = titleDtoMap.map((uiLocaleDto, title) {
      return MapEntry(uiLocaleDto.toString(), title);
    }).toMap();

    return {
      _kCollectionListItemTypeKey: type,
      _kCollectionListItemIdKey: id,
      _kCollectionListItemTitlesKey: titles,
      _kCollectionFolderCollectionsKey: collectionJsons,
    };
  }

  @override
  CollectionFolder toEntity() {
    final titles = titleDtoMap.map((uiLocaleDto, title) {
      return MapEntry(uiLocaleDto.toEntity(), title);
    });

    final collections = collectionDtos.map((collectionDto) {
      return collectionDto.toEntity();
    }).toBuiltList();

    return CollectionFolder(
      id: id,
      titles: titles,
      collections: collections,
    );
  }
}
